package com.rytong.tools.ui;

import java.util.ArrayList;
import com.rytong.tools.utils.Utils;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.TextView;

/**
 * 饼状图控件
 */
public class LPPieChart extends Component {

    public ArrayList<LPSector> sectorList_ = new ArrayList<LPSector>(2);// 组成饼状图的扇形集合

    private int mPointX = 0, mPointY = 0;// 圆心坐标

    private int mRadius = 0;// 半径

    private float preX_;// 记录前一个点的x坐标

    private float preY_;// 记录前一个点的y坐标

    private Bitmap cakeCenter;

    private Bitmap cakePointer;
    
    Paint paint;

    public class MyLPPieChart extends TextView implements CompositedComponent {

        private Paint paint_;
        private LPSector previousSector_;
        private LPSector currentSector_;
        private Paint shadowPaint_;

        public MyLPPieChart(Context context) {
            super(context);
            paint = getPaint();
            paint.setAntiAlias(true);
        }

        /**
         * 初始化扇形列表中所有扇形的起始角度和扫过的角度
         */
         void setupSectors() {
            int size = sectorList_.size();
            float startAngle = 0;
            float sweepAngle = 0;
            for (int i = 0; i < size; i++) {
                LPSector sector = sectorList_.get(i);
                sweepAngle = (float) ((Double.parseDouble((String) sector.getPropertyByName("percent")) / 1) * 360);
                if ((sweepAngle + startAngle) > 360) {
                    sweepAngle = 360 - startAngle;
                }
                if (sweepAngle < 0) {
                    sweepAngle = 0;
                }
                sector.startAngle_ = startAngle;
                sector.sweepAngle_ = sweepAngle;
                startAngle += sweepAngle;
            }

            LPSector selectedSector = null;
            String selected = null;
            for (int i = 0; i < size; i++) {
                selected = (String) sectorList_.get(i).getPropertyByName("selected");
                if (selected != null && selected.trim().equals("selected")) {
                    selectedSector = sectorList_.get(i);
                    break;
                }
            }

            // 加入扇形列表中的扇形的selected = true属性就将其移动到选中位置
            if (selectedSector != null) {
                //初始化饼状图的value值
                property_.put("value", selectedSector.property_.get("value"));
                previousSector_ = selectedSector;
                correctAngle(selectedSector);
            }
        }

        /**
         * 计算指定点的角度
         * 
         * @param x
         * @param y
         * @return
         */
        private int computeAngle(float x, float y) {
            // 两点间距离公式：设A(X1,Y1)、B(X2,Y2)，则∣AB∣=√[(X1－X2)^2+(Y1－Y2)^2]
            float distance = (float) Math.sqrt(((x - mPointX) * (x - mPointX) + (y - mPointY) * (y - mPointY)));
            // 计算弧度
            double radian = Math.acos((x - mPointX) / distance);
            // 度＝弧度×180°/π
            int degree = (int) (radian * 180 / Math.PI);
            if (y < mPointY && degree != 0) {
                degree = 360 - degree;
            }
            return degree;
        }

        /**
         * 重置扇形的起始角度
         * 
         * @param x
         * @param y
         * @param preX
         * @param preY
         */
        private boolean resetSectorsAngle(float x, float y, float preX, float preY) {
            int preAngle = computeAngle(preX, preY);
            int currentAngle = computeAngle(x, y);
            // 转动的角度，顺时针 > 0 逆时针< 0
            int move = currentAngle - preAngle;
            // 下面的判断是针对359度和0度切换时对move的角度进行调整
            if (move < -359)
                move = 1;
            if (move > 359)
                move = -1;
            int size = sectorList_.size();
            for (int i = 0; i < size; i++) {
                sectorList_.get(i).startAngle_ += move;
                // 保证扇形的起始角度范围在0-359度之间
                sectorList_.get(i).startAngle_ = sectorList_.get(i).startAngle_ % 360;
                if (sectorList_.get(i).startAngle_ < 0) {
                    // 逆时针旋转时需要对角度进行调整
                    sectorList_.get(i).startAngle_ += 360;
                }
            }
            return true;
        }

//        @Override
//        public boolean onTouchEvent(MotionEvent event) {
//            boolean isAction = false;
//
//            switch (event.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//            	if(Utils.sc_ != null){
//            		Utils.sc_.focusObj_ = this.composited();
//            	}
//            	if(hs_ != null){
//            		hs_.focusObj_ = this.composited();
//            	}
//            	if(vs_ != null){
//            		vs_.focusObj_ = this.composited();
//            	}
//                // 记录按下的坐标
//                preX_ = event.getX();
//                preY_ = event.getY();
//                isAction = true;
//                break;
//            case MotionEvent.ACTION_UP:
//            	if(Utils.sc_ != null){
//            		Utils.sc_.focusObj_ = null;
//            	}
//            	if(hs_ != null){
//            		hs_.focusObj_ = null;
//            	}
//            	if(vs_ != null){
//            		vs_.focusObj_ = null;
//            	}
//                currentSector_ = computeWhichIsSelected();
//                if (currentSector_ != null) {
//                    //把当前选中的扇形的value值付给饼状图
//                    property_.put("value", property_.get("value"));
//                    isAction = correctAngle(currentSector_);
//                }
//                invalidate();
//                if (previousSector_ != currentSector_ && currentSector_ != null) {
//                    isAction = onClick((String) currentSector_.property_.get("onclick"));
//                    previousSector_ = currentSector_;
//                }
//                break;
//            case MotionEvent.ACTION_MOVE:
//                // 给每个扇形加上转动的角度
//                isAction = resetSectorsAngle(event.getX(), event.getY(), preX_, preY_);
//                // 下一次角度偏移量计算时用到下面记录的x,y坐标
//                preX_ = event.getX();
//                preY_ = event.getY();
//                invalidate();
//                break;
//            }
//            return isAction;
//        }

        /**
         * 计算哪个扇形处于选中状态
         * 
         * @return 被选中的扇形
         */
        private LPSector computeWhichIsSelected() {
            int size = sectorList_.size();
            LPSector sector = null;
            for (int i = 0; i < size; i++) {
                LPSector sectorTemp = sectorList_.get(i);
                // 起始角度小于90°时要求 结束角度start+sweep>90才认为当前扇形被选中
                if (sectorTemp.startAngle_ < 90 && 90 < (sectorTemp.startAngle_ + sectorTemp.sweepAngle_) % 360) {
                    sector = sectorTemp;
                    break;
                }
                // 起始角度大于90°时要求 结束角度start+sweep - 360 >90才认为当前扇形被选中
                if (sectorTemp.startAngle_ > 90 && 90 < (sectorTemp.startAngle_ + sectorTemp.sweepAngle_ - 360)) {
                    sector = sectorTemp;
                    break;
                }
            }
            return sector;
        }

        /**
         * 将指定的扇形矫正到正确的位置（扇形的中心线与90°这条线重合）
         * 
         * @param sector
         */
        private boolean correctAngle(LPSector sector) {
            // System.err.println(sector.desc_);
            // Toast.makeText(getContext(), sector.desc_, Toast.LENGTH_SHORT).show();
            float correctStart = 90 - sector.sweepAngle_ / 2;
            if (correctStart < 0)
                correctStart = 360 + correctStart;
            if ((int) sector.startAngle_ != (int) correctStart) {
                if (sector.startAngle_ > 270)
                    correctStart += 360;
                // 要调整的差值
                float dvalue = correctStart - sector.startAngle_;
                int size = sectorList_.size();
                for (int i = 0; i < size; i++) {
                    sectorList_.get(i).startAngle_ += dvalue;
                }
                return true;
            }
            return false;
        }

        @Override
        public void onDraw(Canvas canvas) {
            // 绘制扇形
            drawSector(canvas);
            // 绘制cakeCenter.png及cakePointer.png
//            drawInteriorCircle(canvas);
//            drawBorder(canvas);
        }

        /**
         * 绘制内部圆及圆心文字
         * 
         * @param canvas
         */
        private void drawInteriorCircle(Canvas canvas) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            // 绘制中间的圆
//            canvas.drawBitmap(cakeCenter, mPointX - (float) cakeCenter.getWidth() / 2, mPointY
//                    - (float) cakeCenter.getHeight() / 2, paint);
            // 绘制小箭头（露出扇形的部分占总的1/3），
            canvas.drawBitmap(cakePointer, mPointX - (float) cakePointer.getWidth() / 2, (mRadius << 1)
                    - (float) cakePointer.getHeight() * 2 / 3, paint);
        }

        /**
         * 绘制列表中的扇形
         * 
         * @param canvas
         */
        private void drawSector(Canvas canvas) {
            paint_ = new Paint();
            shadowPaint_ = new Paint();
            shadowPaint_.setAntiAlias(true);
            RadialGradient radialGradient = new RadialGradient(mPointX, mPointY, mRadius, new int[]{Color.parseColor("#dd000000"),Color.parseColor("#00ffffff"),Color.parseColor("#bbaaaaaa"),Color.parseColor("#bb111111"),Color.parseColor("#33000000")}, new float[]{0.0f,0.75f,0.85f,0.9f,1.25f}, Shader.TileMode.MIRROR);
            shadowPaint_.setShader(radialGradient);
            int size = sectorList_.size();
            paint_.setAntiAlias(true);
            RectF rectF = new RectF(mPointX - mRadius * 15 /16, mPointY - mRadius * 15 /16, mPointX + mRadius * 15 /16, mPointY + mRadius * 15 /16);
            for (int i = 0; i < size; i++) {
                paint_.setColor(sectorList_.get(i).color);
                paint_.setTextSize(sectorList_.get(i).fontSize_);
                // 绘制扇形区域
                canvas.drawArc(rectF, sectorList_.get(i).startAngle_, sectorList_.get(i).sweepAngle_, true, paint_);
                drawContentText(canvas, sectorList_.get(i));
            }
//            canvas.drawCircle(mPointX, mPointX, mRadius, shadowPaint_);
        }

        /**
         * 绘制指定扇形上面的文字
         * 
         * @param canvas
         * @param sector
         */
        private void drawContentText(Canvas canvas, LPSector sector) {
            String value = (String) sector.getPropertyByName("value");
            if (value != null) {
                setTextSize(TypedValue.COMPLEX_UNIT_SP, sector.fontSize_);
                paint.setColor(sector.fontColor_);
                if (sector.fontColor_ > 0) {
                    paint.setColor(sector.fontColor_);
                }
                // 扇形中心线相对于0度线的圆心角
                double rAngle = (sector.startAngle_ + sector.sweepAngle_ / 2) % 360;
                // 位子所画位置到圆心的距离和半径的比
                float a = 1 / 2f;
                float x = mPointX + (float) (a * mRadius * Math.cos(Math.toRadians(rAngle))) - paint.measureText(value)
                        / 2;
                float y = mPointY + (float) (a * mRadius * Math.sin(Math.toRadians(rAngle)));
                
//                FontMetrics fm = paint.getFontMetrics();
//                float fontHeight_ = (float) (Math.ceil(fm.descent - fm.ascent)); // 计算文字的高度
                float fontHeight_ = ((int) (paint.getTextSize() * 3)) >> 2;
            
                canvas.drawText(value, x, (float) (y + 0.5 * fontHeight_), paint);
            }
        }

        @Override
        public Component composited() {
            // TODO Auto-generated method stub
            return LPPieChart.this;
        }
    }

    @Override
    public void initRealView(Activity activity, String nodeValue) {
        realView_ = new MyLPPieChart(activity);
        cakeCenter = Utils.getBitmapFromResources(activity, "cakecenter.png");
        cakePointer = Utils.getBitmapFromResources(activity, "cakepointer.png");
    }

    @Override
    public void mouldH() throws Exception {
        super.mouldH();
        if (sectorList_ == null || sectorList_.isEmpty()) {
            return;
        }
        MyLPPieChart pieChart = (MyLPPieChart) realView_;
        LayoutParams params = (LayoutParams) pieChart.getLayoutParams();
        // 由于扇形的圆心半径都是参照宽来计算的，所以做如下操作
        if (params.width <= 0) {
            int width = sectorList_.get(0).width_;
            if (width <= 0) {
                width = Utils.getScaledValueX(200);
            }
            params.width = width;
            // 指针要露出扇形一部分，所以要保证高比宽的值大一点
            params.height = width + Utils.getScaledValueX(20);
            pieChart.setLayoutParams(params);
        }
        if ((params.height - params.width) < Utils.getScaledValueX(20)) {
            params.height = params.width + Utils.getScaledValueX(20);
            pieChart.setLayoutParams(params);
        }
        // 取宽为计算圆心和半径的参照
        mRadius = Math.min(params.width, params.height) >> 1;
        mPointX = mRadius;
        mPointY = mRadius;
        pieChart.setupSectors();

        float scale = (float) params.width / 3 / cakeCenter.getWidth();
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);// 产生缩放后的Bitmap对象
        cakeCenter = Bitmap.createBitmap(cakeCenter, 0, 0, cakeCenter.getWidth(), cakeCenter.getHeight(),
                matrix, false);

        float scale2 = (float) mRadius / 5 / cakePointer.getWidth();
        Matrix matrix2 = new Matrix();
        matrix2.postScale(scale2, scale2);
        cakePointer = Bitmap.createBitmap(cakePointer, 0, 0, cakePointer.getWidth(), cakePointer
                .getHeight(), matrix2, false);
    }

    public void releaseResource(Component component) {
        super.releaseResource(this);
        if (null != cakeCenter && !cakeCenter.isRecycled())
            cakeCenter.recycle();
        cakeCenter = null;
        if (null != cakePointer && !cakePointer.isRecycled())
            cakePointer.recycle();
        cakePointer = null;
        
        if(null != sectorList_ && sectorList_.size()>0){
        	sectorList_.clear();
        }
        sectorList_ = null;
    }
}
